#ifndef ETHERCATMASTER_H
#define ETHERCATMASTER_H

#include <iostream>
#include "ServoDrive.h"
#include "SafetyModule.h"
#include "Inosv660nDrive.h"
#include "UnknowSlave.h"
#include "xServo.h"

namespace ECatDrv
{
#define PDO_PERIOD_MS   10
// 网卡信息
struct netCardInfo
{
    std::string name;
    std::string id;
};



class EthercatMaster
{
public:
    EthercatMaster();
    ~EthercatMaster();

    /**
     * @brief 网卡扫描
     * @param  card             请加入参数描述
     * @return true 扫描到网卡
     * @return false 未扫描到网卡
     */
    bool NetCardScan(std::vector<netCardInfo> &card);


    /**
     * @brief 主站初始化, 执行后所有从站处于 SAFE_OP状态
     * @param cardId
     * @param info 从站信息
     * @return 0: 正常
     *         -1: ec初始化失败
     *         -2: 未扫描到从站
     *         -3: 有从站未处于SAFE_OP状态
     *         -4: 当前主站已经被初始化
     */
    int MasterInit(std::string cardId, std::vector<std::shared_ptr<EthercatSlave>> &slave, std::vector<std::shared_ptr<ServoDrive>> &servo, std::vector<std::shared_ptr<SafetyModule>> &safety);


    int MasterConfig(std::vector<std::shared_ptr<ECatDrv::EthercatSlave>> &m_slave);

    /**
     * @brief Check the Slave State object
     * @param  state    期望的状态
     * @return true     所有从站都处于期望状态
     * @return false    至少一个从站状态错误
     */
    bool ChkSlaveState(ec_state state);

    /**
     * @brief 设置所有从站到OP状态
     * @return 0:  正常
     *        -1:  当前不处于SAFE_OP
     *        -2:  未跳转到OP状态
     */
    int SetSlavesToOp(void);

    /**
     * @brief 设置所有从站到SafeOP状态
     * @return 0:  正常
     *        -1:  当前已经处于 SafeOP
     *        -2:  未跳转到 SafeOP 状态
     */
    int SetSlavesToSafeOp(void);

    /**
     * @brief 获取从站状态
     * @param state string类型的状态
     */
    void GetAllSlaveState(std::vector<std::string> &state);

    /**
     * @brief 获取从站状态
     * @param state matserState类型的状态
     */
    void GetAllSlaveState(std::vector<masterState> &state);

    /**
     * @brief 设置Sdo信息
     * @param  slave            从站地址 1~n
     * @param  addr             EtherCAT SDO地址
     * @param  size             数据大小
     * @param  data             数据
     */
    void writeSdo(int slave, int addr, int size, uint8_t *data);

    /**
     * @brief 获取Sdo信息
     * @param  slave            从站地址 1~n
     * @param  addr             EtherCAT SDO地址
     * @param  size             数据大小
     * @param  data             数据
     */
    void readSdo(int slave, int addr, int &size, uint8_t *data);


private:
    /**
     * @brief std::string的 trim 实现，去除字符串首尾的空格
     * @param  s                输入字符串
     * @return std::string&     输出字符串
     */
    std::string& trim(std::string &s);

private:
    masterState m_masterState;  // 主站状态
public:
    bool m_masterInited;        // 主站初始化完成标志
};

}

#endif // ETHERCATMASTER_H
